package com.ccp.dev.qbdms.service;

import com.ccp.dev.core.util.BeanUtils;
import com.ccp.dev.core.util.StringPool;
import com.ccp.dev.qbdms.consts.ZhiLiangConst;
import com.ccp.dev.qbdms.dao.CommonalityDao;
import com.ccp.dev.qbdms.model.Commonality;
import com.ccp.dev.qbdms.model.FlowReportDataWrap;
import com.ccp.dev.qbdms.model.SysOrgDeploy;
import com.ccp.dev.qbdms.util.BaseUtil;
import com.ccp.dev.system.model.SysOrg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

/**
 * Created by zzy on 2020/8/24.
 *
 * @Author zzy
 * @Date 2020/8/24
 * @describe 通用异步服务, 放置一些通用的异步方法
 */
@Service
public class CommonalityAsyncService {
    Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private CommonalityService commonalityService;
    @Autowired
    private CommonalityExtendService extendService;
    @Autowired
    private CommonalityDao commonalityDao;
    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    TransactionDefinition transactionDefinition;

    /**
     * 状态位上报异步方法
     *
     * @param commonality
     * @param deployment
     * @param level
     * @throws Exception
     * @author zzy
     */
    @Async("reportAsync")
    public void reportAsyncNoFolw(Commonality commonality, SysOrgDeploy deployment, BaseUtil.SystemLevel level, SysOrg sysOrg) throws Exception {
        String[] businessIds = commonality.getDataId().split(StringPool.COMMA);
        String className = commonality.getClassName();
        String succStatus = level == BaseUtil.SystemLevel.HOSPITALLEVEL ? ZhiLiangConst.GROUP_TOBECONFIRMED : ZhiLiangConst.REPORT_STATUS_GROUPTOBEREPORTED;
        String failStatus = level == BaseUtil.SystemLevel.HOSPITALLEVEL ? ZhiLiangConst.REPORT_STATUS_REPORTGROUPFAILURE : ZhiLiangConst.REPORT_STATUS_TEMP_REPORTTOTHEHOSPITAL_FAILURE;
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            // 集中
            if (BeanUtils.isEmpty(deployment) || ZhiLiangConst.DEPMETHOND_CENTER.equals(deployment.getDepmethod())) {
                // 集中部署时,如果是院级上报集团则尝试进行归零确认
                if (level == BaseUtil.SystemLevel.HOSPITALLEVEL) {
                    // 如果归零成功,则更新上报状态到 已确认
                    boolean result = extendService.zeroHandler(commonality.getDataId(), commonality.getClassName(), deployment);
                    commonalityService.addAndUpdateES(commonality.getTableName(), commonality.getDataId(), result ? ZhiLiangConst.GROUP_CONFIRMED : ZhiLiangConst.GROUP_TOBECONFIRMED, sysOrg);
                    if (!result) {
                        // 归零失败,或无需归零则状态为 未确认
                        commonalityDao.reportPlant(commonality.getTableName(), businessIds, ZhiLiangConst.GROUP_TOBECONFIRMED);
                    }
                }
                else {
                    commonalityDao.reportPlant(commonality.getTableName(), businessIds, succStatus);
                }
                if (org.apache.commons.lang3.StringUtils.isNotBlank(className) && className.equals("wQbdFlightJc")) {
                    commonalityService.sendReportMsg(className,  commonality.getDataId(), succStatus, deployment);
                }
                // 上报成功后一些后置处理,放在这个方法中统一处理.
                extendService.reportSuccPostHandler(commonality.getDataId(), commonality.getClassName());
                dataSourceTransactionManager.commit(transactionStatus);
                return;
            }
            //分级  分级部署时,归零是在接收方处理
            boolean apiResult = commonalityService.sendReportMsg(commonality.getClassName(), commonality.getDataId(), succStatus, deployment);
            if (level == BaseUtil.SystemLevel.HOSPITALLEVEL) {
                //根据接口的结果去更新es中数据的状态
                commonalityService.addAndUpdateES(commonality.getTableName(), commonality.getDataId(),
                        apiResult ? ZhiLiangConst.GROUP_TOBECONFIRMED : ZhiLiangConst.REPORT_STATUS_REPORTGROUPFAILURE, sysOrg);
            }
            // 根据接口结果去更新数据上报状态
            if (apiResult) {
                commonalityDao.reportPlant(commonality.getTableName(), businessIds, succStatus);
                extendService.reportSuccPostHandler(commonality.getDataId(), commonality.getClassName());
            }
            else {
                commonalityDao.reportPlant(commonality.getTableName(), businessIds, failStatus);
            }
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
            dataSourceTransactionManager.rollback(transactionStatus);
            // 出现异常,更新数据状态为上报失败
            extendService.addLocalStatusDoing(commonality.getDataId(), failStatus, commonality.getTableName());
            log.error("异步上报服务异常 -> {}", e.getMessage());
            throw e;
        }
    }


    /**
     * 流程上报的异步方法
     *
     * @param flowData 封装了一个上报参数对象
     * @author zzy
     */
    @Async("reportAsync")
    //@Transactional(rollbackFor = Exception.class)
    public void reportAsyncFolw(FlowReportDataWrap flowData) throws Exception {
        BaseUtil.SystemLevel level = flowData.getLevel();
        String succStatus = level == BaseUtil.SystemLevel.HOSPITALLEVEL ? ZhiLiangConst.GROUP_TOBECONFIRMED : ZhiLiangConst.REPORT_STATUS_GROUPTOBEREPORTED;
        String failStatus = level == BaseUtil.SystemLevel.HOSPITALLEVEL ? ZhiLiangConst.REPORT_STATUS_REPORTGROUPFAILURE : ZhiLiangConst.REPORT_STATUS_TEMP_REPORTTOTHEHOSPITAL_FAILURE;
        // 内部审批状态 报集团未通过,报院未通过
        String flowFail = level == BaseUtil.SystemLevel.HOSPITALLEVEL ? ZhiLiangConst.REPORT_STATUS_FAILEDTOSUBMITTOTHEGROUPFORAPPROVAL : ZhiLiangConst.REPORT_STATUS_TEMP_FAILEDPASSAPPROVALOFTHEHOSPITAL;
        String businessId = flowData.getBusinessId();
        String successDataId = flowData.getSuccessDataId();
        String className = flowData.getClassName();
        String tableName = flowData.getTableName();
        SysOrgDeploy dep = flowData.getDep();
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            // 如果是勾选数据后点击同意的,处理未勾选的数据为审批未通过
            commonalityDao.updateBusinessStatusHospitalFail(businessId, tableName, flowFail);
            // 集中
            if (BeanUtils.isEmpty(dep) || ZhiLiangConst.DEPMETHOND_CENTER.equals(dep.getDepmethod())) {
                if (level == BaseUtil.SystemLevel.HOSPITALLEVEL) {
                    // 尝试归零
                    boolean result = extendService.zeroHandler(successDataId, className, dep);
                    //通过数据修改状态为报集团成功
                    commonalityService.addAndUpdateES(tableName, successDataId, result ? ZhiLiangConst.GROUP_CONFIRMED : ZhiLiangConst.GROUP_TOBECONFIRMED, flowData.getSysOrg());
                    if (!result) {
                        commonalityDao.updateBusinessStatusHospital(businessId, tableName, ZhiLiangConst.GROUP_TOBECONFIRMED);
                    }
                }
                else {
                    commonalityDao.updateBusinessStatusHospital(businessId, tableName, succStatus);
                }
                if (org.apache.commons.lang3.StringUtils.isNotBlank(className) && className.equals("wQbdFlightJc")) {
                    commonalityService.sendReportMsg(className, successDataId, succStatus, dep);
                }
                // 如果是勾选数据后点击同意的,处理未勾选的数据为审批未通过
                //commonalityDao.updateBusinessStatusHospitalFail(businessId, tableName, flowFail);
                // 上报成功后一些后置处理,放在这个方法中统一处理.
                extendService.reportSuccPostHandler(successDataId, className);
                dataSourceTransactionManager.commit(transactionStatus);
                return;
            }

            // 分级
            boolean apiResult = commonalityService.sendReportMsg(className, successDataId, succStatus, dep);
            if (level == BaseUtil.SystemLevel.HOSPITALLEVEL) {
                //通过数据修改状态为报集团成功
                commonalityService.addAndUpdateES(tableName, successDataId,
                        apiResult ? ZhiLiangConst.GROUP_TOBECONFIRMED : ZhiLiangConst.REPORT_STATUS_REPORTGROUPFAILURE, flowData.getSysOrg());
            }
            // 根据接口结果去更新数据上报状态
            if (apiResult) {
                commonalityDao.updateBusinessStatusHospital(businessId, tableName, succStatus);
            }
            else {
                commonalityDao.updateBusinessStatusHospital(businessId, tableName, failStatus);
            }
            extendService.reportSuccPostHandler(successDataId, className);
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
            dataSourceTransactionManager.rollback(transactionStatus);
            // 出现异常,更新数据状态为上报失败
            extendService.addLocalStatusDoing(successDataId, failStatus, tableName);
            log.error("异步上报服务异常 -> {}", e.getMessage());
            e.printStackTrace();
            throw e;
        }

    }
}
